Nos proponemos hacer un programa que sea como una calculadora, si le entras 5 + 2 contesta 7 y si pones 3.0 * 2.5 contesta 7.5. Queremos poder operar con números reales y tener las 4 operaciones básicas: +, -, * y /.
Para hacer este programa empezaremos leyendo un real, luego un caracter, y luego otro real. Los reales son los operandos y el caracter es el operador. A continuación miraremos el operador y mostraremos por pantalla el resultado de la operación. Este es el programa que implementa la suma
#include <iostream> using namespace std; int main() { double x, y; char op; cin >> x >> op >> y; if (op == '+') { cout << x + y << endl; } else { cout << x - y << endl; } }
En esta primera versión, el programa solamente mira si la operación es una suma y entonces muestra una suma. Pero si la operación no es una suma (y podría ser una multiplicación o una resta o una división) mostrará una resta por pantalla, sin importar la operación. Para ser la primera versión del programa no está mal porque ya tenemos las bases funcionando, pero hay que arreglar la discriminación de los operadores.
El problema está en el else, porque se coge esa opción cuando el if da false y eso es cuando la operación op no es '+'. Pero entonces puede ser cualquier cosa (incluso un caracter como un '?'). Pruébalo si quieres.
Lo que habría que hacer es discriminar mejor en el else, y para hacerlo hay que poner otro if dentro del ``else``. El if-else anterior quedaría así:
if (op == '+') { cout << x + y; } else { if (op == '-') { cout << x - y; } else { cout << "No entiendo la operación '" << op << "'"; } } cout << endl;
Ahora, cuando entramos en el primer else para hacer una operación que no es la suma comprobamos que realmente tengamos una resta y si no, decimos que no entendemos (aún) el operador que sea. Hay otros dos detallitos:
Este if-dentro-de-if se puede representar, con los diagramas que hemos usado hasta ahora, así:
Ahora quedaría añadir las dos operaciones que nos faltan. Si añadimos la primera nos vuelve a pasar que hay que poner un if dentro de otro:
if (op == '+') { cout << x + y; } else { if (op == '-') { cout << x - y; } else { if (op == '*') { cout << x * y; } else { cout << "No entiendo la operación '" << op << "'"; } } } cout << endl;
Empieza a ser evidente que si no se indenta bien el programa (se organizan los espacios a la derecha correspondiendo a los bloques), se hace difícilmente comprensible.
Finalmente añadimos la división:
if (op == '+') { cout << x + y; } else { if (op == '-') { cout << x - y; } else { if (op == '*') { cout << x * y; } else { if (op == '/') { cout << x / y; } else { cout << "No entiendo la operación '" << op << "'"; } } } } cout << endl;
Aunque el programa ahora funciona, tiene un aspecto un poco intimidatorio. Las líneas se van metiendo a la derecha porque los ifs-dentro-de-ifs así lo requiren. Para pintar el diagrama de este último if haría falta buena parte de la pantalla (pero pruébalo tu en papel).
El último paso es, entonces, mantener el programa tal como está pero reescribirlo para que sea más legible. El aspecto de un programa es muy importante para su comprensión. El mismo programa mal escrito puede ser mucho más difícil de comprender y como que la programación ya es complicada de por sí, es mejor no añadir dolor de cabeza al que lee el programa (que podemos ser nosotros mismos en unos días).
La manera de arreglar un poco este programa es hacer lo siguiente:
El resultado será el siguiente:
if (op == '+') { cout << x + y; } else if (op == '-') { cout << x - y; } else { if (op == '*') { cout << x * y; } else { if (op == '/') { cout << x / y; } else { cout << "No entiendo la operación '" << op << "'"; } } } cout << endl;
Ahora la resta parece que está a la misma altura que la suma, pese a que sabemos que ese if está dentro de la rama else del primero.
Si hacemos lo mismo para el segundo else tendremos:
if (op == '+') { cout << x + y; } else if (op == '-') { cout << x - y; } else if (op == '*') { cout << x * y; } else { if (op == '/') { cout << x / y; } else { cout << "No entiendo la operación '" << op << "'"; } } cout << endl;
Y para el tercero sería:
if (op == '+') { cout << x + y; } else if (op == '-') { cout << x - y; } else if (op == '*') { cout << x * y; } else if (op == '/') { cout << x / y; } else { cout << "No entiendo la operación '" << op << "'"; } cout << endl;
Ahora, pese a que el programa es el mismo exactamente, su lectura es bastante diferente. Aún así hay que pensar que la forma de ejecutarse es la misma, solo hemos cambiado un poco la "presentación" del código fuente. Lo que hemos ganado es que el if escrito así parece como si tuviera 5 alternativas y no 2. Es decir, aunque para tener 5 alternativas hay que poner 4 ifs, la apariencia es que las 4 operaciones más el mensaje de "no entiendo" tienen el mismo nivel, por decirlo así.
Los ifs muy "profundos" (con muchos niveles) donde las alternativas son muy parecidas es importante escribirlos así para ayudar a su comprensión.
Haz un programa que te pida un día de la semana y devuelva el día en números. Si el día entrado es "lunes", el programa muestra 1, si es "martes" muestra un 2, y así hasta el "domingo" que es el 7.
Haz un programa que te pide una calificación textual como "Aprovado", "Notable", "Excelente" o "Matrícula de Honor" y devuelve la nota asociada (5, 7, 9 o 10, respectivamente).
Puedes ver un fallo en las llaves ({ y }) del siguiente código?
char tecla; cin >> tecla; if (tecla == 'a') { cout << 'A' << endl; } else { if (tecla == 'b') { cout << 'B' << endl; } else { if (tecla == 'c') { cout << 'C'; } else { if (tecla == 'd') { cout << 'D'; } else { cout << "otra tecla"; } } } cout << endl;
Corrige la indentación primero y luego buscas la llave errónea.
En preparación